﻿using Prism.Dialogs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using YY.Admin.Core;
using YY.Admin.Core.Extension;
using YY.Admin.Core.Util;
using YY.Admin.Services.Service.Auth;
using YY.Admin.Views;

namespace YY.Admin.ViewModels
{
    public class BaseViewModel : BindableBase
    {
        private bool _isLoading;
        private string _title = string.Empty;
        // 添加Token检查定时器
        private static DispatcherTimer _tokenCheckTimer;
        /// <summary>
        ///加载
        /// </summary>
        public bool IsLoading
        {
            get => _isLoading;
            set => SetProperty(ref _isLoading, value);
        }
        /// <summary>
        ///标题
        /// </summary>
        public string Title
        {
            get => _title;
            set => SetProperty(ref _title, value);
        }
        private readonly IDialogService _dialogService;
        protected readonly IRegionManager _regionManager;
        /// <summary>
        /// 日志对象
        /// </summary>

        protected ILoggerService _logger;
        /// <summary>
        /// 依赖注入容器
        /// </summary>
        protected IContainerExtension _container { get; }
        /// <summary>
        /// 事件汇总器，用于发布或订阅事件
        /// </summary>
        protected IEventAggregator _eventAggregator;
        /// <summary>
        /// 区域管理器
        /// </summary>
        protected IRegionManager _RegionManager => _regionManager;
        /// <summary>
        /// 当前已登录用户信息
        /// </summary>
        protected static UserContext _userContext { get; set; }

        protected BaseViewModel(IContainerExtension container)
        {
            _container = container;
            _logger = container.Resolve<ILoggerService>();
            _eventAggregator = container.Resolve<IEventAggregator>();
            this._dialogService = container.Resolve<IDialogService>();
            this._regionManager = container.Resolve<IRegionManager>();
        }

        #region 用户操作
        // 启动定时器的方法
        public static void StartTokenCheckTimer()
        {
            if (_tokenCheckTimer == null)
            {
                _tokenCheckTimer = new DispatcherTimer
                {
                    Interval = TimeSpan.FromMinutes(1)
                };
                _tokenCheckTimer.Tick += CheckTokenExpiration;
            }

            if (!_tokenCheckTimer.IsEnabled)
            {
                _tokenCheckTimer.Start();
            }
        }

        // 停止定时器的方法
        public static void StopTokenCheckTimer()
        {
            if (_tokenCheckTimer != null && _tokenCheckTimer.IsEnabled)
            {
                _tokenCheckTimer.Stop();
            }
        }
        /// <summary>
        ///定时器检查方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void CheckTokenExpiration(object sender, EventArgs e)
        {
            // 确保在主线程执行
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (UserContext == null || UserContext.Token == null)
                {
                    // 如果没有用户信息，停止定时器
                    StopTokenCheckTimer();
                    return;
                }

                var authService = ContainerLocator.Current.Resolve<ISysAuthService>();
                if (!authService.ValidateToken(UserContext.Token.AccessToken))
                {
                    // 停止定时器防止重复触发
                    StopTokenCheckTimer();

                    // 显示过期提示
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        var currentWindow = Application.Current.MainWindow;
                        if (currentWindow != null)
                        {
                            var viewModel = currentWindow.DataContext as BaseViewModel;
                            viewModel?.ForceLogout("您的登录已过期，请重新登录");
                        }
                    });
                }
            });
        }
        /// <summary>
        /// 强制退出方法
        /// </summary>
        /// <param name="message"></param>
        public async void ForceLogout(string message)
        {
            // 先显示对话框
            await ShowAlertAsync(message);

            // 停止定时器
            BaseViewModel.StopTokenCheckTimer();
            // 清除用户上下文
            BaseViewModel.ClearUserContext();
            // 再执行退出操作
            var authService = _container.Resolve<ISysAuthService>();
            await authService.LogoutAsync();
          
            // 跳转到登录页
            var loginWindow = _container.Resolve<LoginWindow>();

            // 安全关闭当前窗口
            if (Application.Current.MainWindow != null)
            {
                Application.Current.MainWindow.Hide();
                Application.Current.MainWindow.Close();
            }

            Application.Current.MainWindow = loginWindow;
            loginWindow.Show();
        }
        public static UserContext UserContext
        {
            get => _userContext;
            private set
            {
                if (_userContext != value)
                {
                    _userContext = value;
                    // 通知静态属性变化（需要额外实现）
                   StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(UserContext)));
                }
            }
        }
        // 静态属性变更通知事件
        public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
        /// <summary>
        /// 设置用户上下文
        /// </summary>
        /// <param name="user"></param>
        /// <param name="token"></param>
        public static void SetUserContext(SysUser user, UserToken token)
        {
            UserContext = new UserContext
            {
                UserId = user.Id,
                TenantId = user.TenantId!.Value,
                Account = user.Account,
                AccountType = user.AccountType,
                RealName = user.RealName,
                IsSuperAdmin = user.AccountType == AccountTypeEnum.SuperAdmin,
                OrgId = user.OrgId,
                Token = token
            };
        }
        /// <summary>
        /// 清除用户上下文
        /// </summary>
        public static void ClearUserContext()
        {
            UserContext = null;
        }
        #endregion

        #region 导航
        /// <summary>
        /// 导航到指定Page
        /// </summary>
        /// <param name="regionName">区域名称</param>
        /// <param name="target">目标Page名称</param>
        /// <param name="navigationCallback">导航回调函数</param>
        protected void RequestNavigate(string regionName, string target, Action<NavigationResult> navigationCallback = null)
        {
            IRegion region = _regionManager.Regions[regionName];
            if (region == null) return;
            region.RemoveAll();
            if (navigationCallback != null)
                region.RequestNavigate(target, navigationCallback);
            else
                region.RequestNavigate(target);
        }

        protected void SetRegionManager(DependencyObject target)
        {
            RegionManager.SetRegionManager(target, _regionManager);
        }
        /// <summary>
        /// 安全导航到指定视图
        /// </summary>
        protected void SafeNavigate(string regionName, string targetView, NavigationParameters parameters = null)
        {
            ExecuteWithExceptionHandling(() =>
            {
                // 导航页面
                _regionManager.RequestNavigate(regionName, targetView, parameters);
            });
        }
        protected void ExecuteWithExceptionHandling(Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }

        private void HandleException(Exception ex)
        {
            LogError("操作发生异常", ex);
            // ShowErrorDialog($"操作异常: {ex.Message}");
        }
        #endregion

        #region 弹出框
        /// <summary>
        /// 弹框提示
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="callback">回调函数</param>
        protected void Alert(string message, Action<IDialogResult> callback = null)
        {
            _dialogService.ShowDialog("AlertDialog", new DialogParameters($"message={message}"), callback);
        }
        protected Task ShowAlertAsync(string message)
        {
            var tcs = new TaskCompletionSource<bool>();
            Alert(message,result => tcs.SetResult(true));
            return tcs.Task;
        }
        /// <summary>
        /// 弹出消息提示框，1秒钟自动关闭
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="messageType">消息类型</param>
        /// <param name="callback">回调函数</param>
        protected void AlertPopup(string message, MessageTypeEnum messageType = MessageTypeEnum.Success, Action<IDialogResult> callback = null)
        {
            switch (messageType)
            {
                case MessageTypeEnum.Success:
                    _dialogService.ShowDialog("SuccessDialog", new DialogParameters($"message={message}"), callback);
                    break;
                case MessageTypeEnum.Error:
                    _dialogService.ShowDialog("ErrorDialog", new DialogParameters($"message={message}"), callback);
                    break;
                case MessageTypeEnum.Warning:
                    _dialogService.ShowDialog("WarningDialog", new DialogParameters($"message={message}"), callback);
                    break;
                default:
                    _dialogService.ShowDialog("SuccessDialog", new DialogParameters($"message={message}"), callback);
                    break;
            }
        }

        /// <summary>
        /// 确认框提示
        /// </summary>
        /// <param name="message">确认框消息</param>
        /// <param name="callback">回调函数</param>
        protected void Confirm(string message, Action<IDialogResult> callback = null)
        {
            _dialogService.ShowDialog("ConfirmDialog", new DialogParameters($"message={message}"), callback);
        }
        #endregion

        #region 日志功能封装
        protected void LogInfo(string message, [CallerMemberName] string caller = "")
           => _logger.Information($"[{GetType().Name}.{caller}] {message}");

        protected void LogWarning(string message, [CallerMemberName] string caller = "")
            => _logger.Warning($"[{GetType().Name}.{caller}] {message}");

        protected void LogError(string message, Exception ex = null, [CallerMemberName] string caller = "")
            => _logger.Error($"[{GetType().Name}.{caller}] {message}", ex);
        #endregion

        /// <summary>
        /// 异常处理封装
        /// </summary>
        /// <param name="asyncAction"></param>
        /// <param name="onFinally"></param>
        /// <returns></returns>
        protected async Task ExecuteAsync(Func<Task> asyncAction, Action onFinally = null)
        {
            try
            {
                IsLoading = true;
                await asyncAction();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                IsLoading = false;
                onFinally?.Invoke();
            }
        }

        /// <summary>
        /// 窗口管理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        protected void SwitchMainWindow<T>() where T : Window
        {
            ExecuteWithExceptionHandling(() =>
            {
                var currentWindow = Application.Current.MainWindow;
                var newWindow = _container.Resolve<T>();

                Application.Current.MainWindow?.Hide();
                Application.Current.MainWindow = newWindow;
                newWindow.Show();

                currentWindow?.Close();
            });
        }

        /// <summary>
        /// 资源管理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="resourceKey"></param>
        /// <returns></returns>
        /// <exception cref="ResourceNotFoundException"></exception>
        protected T GetResource<T>(string resourceKey)
        {
            if (Application.Current.TryFindResource(resourceKey) is T resource)
            {
                return resource;
            }
            throw new ResourceNotFoundException($"资源未找到: {resourceKey}");
        }
    }

    // 自定义异常类型
    public class ResourceNotFoundException : Exception
    {
        public ResourceNotFoundException(string message) : base(message) { }
    }
}
